#ifndef GAME_ENGINE_H_
#define GAME_ENGINE_H_

#include "stdafx.h"
#include "camera_view.h"
#include "game_camera.h"
#include "actor.h"
#include "game_level.h"

#ifdef NDEBUG
#	define OGRE_CFG_PATH				"./../data/config/ogre.cfg"
#	define OGRE_CFG_PLUGINS_PATH		"./../data/config/plugins.cfg"
#	define OGRE_LOG_PATH				"./../data/log/Ogre.log"
#elif (defined _DEBUG)
#	define OGRE_CFG_PATH				"./../data/config/ogre.cfg"
#	define OGRE_CFG_PLUGINS_PATH		"./../data/config/plugins_d.cfg"
#	define OGRE_LOG_PATH				"./../data/log/Ogre.log"
#endif /* NDEBUG */

namespace rpg {

	class GameEngine : public Ogre::FrameListener {
	public:
		/* constructors and destructors */
		GameEngine(void);
		~GameEngine(void);

		/* public methods to handle game flow */
		void initializeGraphics(void);
		void initializeInput(void);
		void runGameLoop(void);

		/* public methods to handle game events */
		bool frameStarted(const Ogre::FrameEvent& evt);
		bool frameRenderingQueued(const Ogre::FrameEvent& evt);
		bool frameEnded(const Ogre::FrameEvent& evt);

		/* public method to legal quit */
		void quit(void);
	private:
		/* Ogre render system data */
		Ogre::Root *mOgreRoot;
		Ogre::RenderWindow *mOgreWindow;
		Ogre::SceneManager *mOgreScene;
		Ogre::Camera *mCamera;
		Ogre::Viewport *mViewport;
		int mScreenWidth;
		int mScreenHeight;
		int mMouseX;
		int mMouseY;

		/* Input system data */
		OIS::InputManager *mInputManager;
		OIS::Keyboard *mKeyboard;
		OIS::Mouse *mMouse;
		OIS::MouseState mOldMouseState;

		/* GUI System */
		CEGUI::OgreCEGUIRenderer *mGuiRenderer;
		CEGUI::System *mGuiSystem;
		CEGUI::WindowManager *mGuiWindowManager;	
		CEGUI::Window *mGuiSheet;

		/* common game data */
		bool mQuitFlag;
		float mKeyboardNextRepeat;
		float mMouseSensivity;
		GameLevel mGameLevel;
		Ogre::Vector3 mCrossPosition;
		Ogre::SceneNode *mCrossNode;

		/* temporary functions for loading scene */
		void loadScene(void);
		void loadSceneEnvironment(void);
		void loadSceneCamera(void);
		void loadSceneGeometry(void);

		/* graphics initialization functions */
		void loadOgreRuntime(void);
		void loadOgreResourcesPath(void);
		void loadOgreRenderSystem(void);
		void loadOgreGraphicsResources(void);
		void loadOgreScene(void);

		/* input system initialization functions */
		void loadInputSystem(void);
		void captureKeyboard(void);
		void captureMouse(void);
		void processKeyboard(float deltaTime);
		void processMouse(float deltaTime);

		/* gui initialization */
		void loadCEGUI(void);
		void loadGUIScheme(void);
		bool ceguiEvent(const CEGUI::EventArgs &e);

		/* ogre systems */
		void updateOgreSystems(float deltaTime);
		void updateOgreAnimations(float deltaTime);
	};

}

#endif /* GAME_ENGINE_H_ */
